#region using directives

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Client.CCS;
using Client.UIHelper;
using DataStore=Client.UIHelper.DataStore;

#endregion

namespace ClientForms
{
    /// <summary>
    /// The buy now form provides users a way to purchase and activate the application.  The default
    /// payment integration is with PayPal.
    /// </summary>
    /// <exception cref="DataStoreAppConfigException">
    /// If the datastore has not been initialized before the form was created this exception will be thrown.
    /// </exception>
    public class BuyNowForm : Form
    {
        #region Private variables

        private Button back;
        private Panel bottomPanel;
        private Button cancel;
        private IContainer components;
        private DataStore dataStore;
        private bool enterProductKey = false;
        private RadioButton enterProductKeyRadio;
        private ErrorProvider errorProvider1;
        private Graphics grfx;
        private BuyNowHelper m_buynowhelper;
        private Formstate m_eFormState;
        private Panel middlePanel;
        private Button next;
        private bool purchaseProductKey = false;
        private RadioButton purchaseProductRadio;
        private Panel topPanel;

        private enum Formstate
        {
            Initial,
            Buynowprocessing,
            Buynowprocessingcomplete,
            BuyNowError,
            ActivateNow,
            ActivateNowProcessing,
            ActivateNowProcessingComplete,
            ActivateNowError,
            Registrationprocessing,
            Registrationprocessingcomplete,
            SelectLicensing,
            Error
        }

        #endregion

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.topPanel = new System.Windows.Forms.Panel();
            this.middlePanel = new System.Windows.Forms.Panel();
            this.enterProductKeyRadio = new System.Windows.Forms.RadioButton();
            this.purchaseProductRadio = new System.Windows.Forms.RadioButton();
            this.bottomPanel = new System.Windows.Forms.Panel();
            this.back = new System.Windows.Forms.Button();
            this.cancel = new System.Windows.Forms.Button();
            this.next = new System.Windows.Forms.Button();
            this.errorProvider1 = new System.Windows.Forms.ErrorProvider(this.components);
            this.middlePanel.SuspendLayout();
            this.bottomPanel.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize) (this.errorProvider1)).BeginInit();
            this.SuspendLayout();
            // 
            // topPanel
            // 
            this.topPanel.BackColor = System.Drawing.Color.Transparent;
            this.topPanel.Dock = System.Windows.Forms.DockStyle.Top;
            this.topPanel.Location = new System.Drawing.Point(0, 0);
            this.topPanel.Name = "topPanel";
            this.topPanel.Size = new System.Drawing.Size(569, 51);
            this.topPanel.TabIndex = 0;
            // 
            // middlePanel
            // 
            this.middlePanel.BackColor = System.Drawing.Color.Transparent;
            this.middlePanel.Controls.Add(this.enterProductKeyRadio);
            this.middlePanel.Controls.Add(this.purchaseProductRadio);
            this.middlePanel.Dock = System.Windows.Forms.DockStyle.Fill;
            this.middlePanel.Location = new System.Drawing.Point(0, 51);
            this.middlePanel.Name = "middlePanel";
            this.middlePanel.Size = new System.Drawing.Size(569, 363);
            this.middlePanel.TabIndex = 1;
            // 
            // enterProductKeyRadio
            // 
            this.enterProductKeyRadio.AutoSize = true;
            this.enterProductKeyRadio.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte) (0)));
            this.enterProductKeyRadio.Location = new System.Drawing.Point(170, 150);
            this.enterProductKeyRadio.Name = "enterProductKeyRadio";
            this.enterProductKeyRadio.Size = new System.Drawing.Size(169, 22);
            this.enterProductKeyRadio.TabIndex = 6;
            this.enterProductKeyRadio.TabStop = false;
            this.enterProductKeyRadio.Text = "Enter a product key";
            // 
            // purchaseProductRadio
            // 
            this.purchaseProductRadio.AutoSize = true;
            this.purchaseProductRadio.Checked = true;
            this.purchaseProductRadio.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte) (0)));
            this.purchaseProductRadio.Location = new System.Drawing.Point(170, 105);
            this.purchaseProductRadio.Name = "purchaseProductRadio";
            this.purchaseProductRadio.Size = new System.Drawing.Size(200, 22);
            this.purchaseProductRadio.TabIndex = 5;
            this.purchaseProductRadio.Text = "Purchase a product key";
            // 
            // bottomPanel
            // 
            this.bottomPanel.BackColor = System.Drawing.Color.Transparent;
            this.bottomPanel.Controls.Add(this.back);
            this.bottomPanel.Controls.Add(this.cancel);
            this.bottomPanel.Controls.Add(this.next);
            this.bottomPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.bottomPanel.Location = new System.Drawing.Point(0, 365);
            this.bottomPanel.Name = "bottomPanel";
            this.bottomPanel.Size = new System.Drawing.Size(569, 49);
            this.bottomPanel.TabIndex = 2;
            // 
            // back
            // 
            this.back.Enabled = false;
            this.back.Location = new System.Drawing.Point(392, 11);
            this.back.Name = "back";
            this.back.Size = new System.Drawing.Size(75, 23);
            this.back.TabIndex = 3;
            this.back.Text = "< Back";
            this.back.Click += new System.EventHandler(this.back_Click);
            // 
            // cancel
            // 
            this.cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.cancel.Location = new System.Drawing.Point(280, 11);
            this.cancel.Name = "cancel";
            this.cancel.Size = new System.Drawing.Size(75, 23);
            this.cancel.TabIndex = 2;
            this.cancel.Text = "Cancel";
            // 
            // next
            // 
            this.next.Location = new System.Drawing.Point(479, 11);
            this.next.Name = "next";
            this.next.Size = new System.Drawing.Size(75, 23);
            this.next.TabIndex = 1;
            this.next.Text = "Next >";
            this.next.Click += new System.EventHandler(this.next_Click);
            // 
            // errorProvider1
            // 
            this.errorProvider1.ContainerControl = this;
            // 
            // BuyNowForm
            // 
            this.AcceptButton = this.next;
            this.BackColor = System.Drawing.Color.Silver;
            this.BackgroundImage = ClientForms.Resource.activation_options;
            this.CancelButton = this.cancel;
            this.ClientSize = new System.Drawing.Size(569, 414);
            this.Controls.Add(this.bottomPanel);
            this.Controls.Add(this.middlePanel);
            this.Controls.Add(this.topPanel);
            this.Name = "BuyNowForm";
            this.ShowInTaskbar = false;
            this.Text = "BuyNowForm";
            this.middlePanel.ResumeLayout(false);
            this.middlePanel.PerformLayout();
            this.bottomPanel.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize) (this.errorProvider1)).EndInit();
            this.ResumeLayout(false);
        }


        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        #endregion

        #region Constructors

        /// <summary>
        /// The constructor for the buy now form.
        /// </summary>
        /// <exception cref="DataStoreAppConfigException">
        /// If the datastore has not been initialized before the form was created this exception will be thrown.
        /// </exception>
        public BuyNowForm()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            dataStore = new DataStore(this);

            ///Initialize the buy now helper class and pass in a reference to the current form.
            m_buynowhelper = new BuyNowHelper(this);

            ///Set up the required event handlers for processing failed and processing complete.
            m_buynowhelper.ProcessingComplete += new EventHandler<ProcessingCompletedEvent>(ProccessingComplete);
            m_buynowhelper.ProcessingFailed += new EventHandler<ProcessingFailedEvent>(ProccessingFailed);

            ///Set up the event handler to capture the form closing event so clean up can be done.
            Closing += new CancelEventHandler(BuyNowForm_Closing);

            ///Create the variable to hold form state and set to initial
            m_eFormState = new Formstate();
            m_eFormState = Formstate.Initial;


            if (dataStore.PaymentSettings == null)
            {
                string message = "You Cannot use this form until a valid datastore has been received from the web service.";
                MessageBox.Show(message);
                Close();
                throw new DataStoreAppConfigException(message);
            }
        }

        #endregion

        #region Form Event Handlers

        /// <summary>
        /// Called by BuyNowHelper on processing completion.
        /// The event triggers the form to go into the completion stage and show the completion message.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ProccessingComplete(object sender, ProcessingCompletedEvent e)
        {
            // Map the delegate to the instance method:
            var d = new MarshallThisFuncString(SetFormBuyNowProcessingComplete);

            //invoke on the original form reference
            e.FormReference.Invoke(d, new object[] {e.Message});
        }

        /// <summary>
        /// Called by BuyNowHelper on processing failed.
        /// When processing fails pass the message received in the eventargs to be displayed for the user.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ProccessingFailed(object sender, ProcessingFailedEvent e)
        {
            Debug.WriteLine("Processing Failed Buy Now Form: " + e.Message);

            // Map the delegate to the instance method:
            var d = new MarshallThisFuncFailureInfo(SetFormBuyNowProcessingFailed);

            //invoke on the original form reference
            e.FormReference.Invoke(d, new object[] {e.FailureInformation});
        }


        /// <summary>
        /// The event handler for the cancel button closes the form.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        /// <summary>
        /// The event handler for form closing.  This gives us a chance to cancel web service calls and do cleanup before the
        /// form is disposed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BuyNowForm_Closing(object sender, CancelEventArgs e)
        {
            m_buynowhelper.Cancelprocessing();
        }

        /// <summary>
        /// The event handler for the form next button.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void next_Click(object sender, EventArgs e)
        {
            var validator = new FormValidator.ControlValidator(FormValidator.Hastextvalidator);

            switch (m_eFormState)
            {
                case Formstate.Initial:
                    if (purchaseProductRadio.Checked)
                    {
                        purchaseProductKey = true;
                        enterProductKey = false;
                        SetFormSelectLicensingLevel();
                    }
                    if (enterProductKeyRadio.Checked)
                    {
                        purchaseProductKey = false;
                        enterProductKey = true;
                        SetFormActivateNow();
                    }


                    break;
                case Formstate.SelectLicensing:
                    ///The user is proceeding to buy a new product key.
                    if (purchaseProductKey)
                    {
                        SetFormBuyNowProcessing();
                    }

                    break;
                case Formstate.ActivateNow:
                    ///Validate the product key enter box to make sure it is not blank.                    
                    if (FormValidator.Fieldisvalid(errorProvider1, middlePanel.Controls.Find("productKey", false)[0], "Please enter a valid Product Key.", validator))
                    {
                        SetFormActivateNowProcessing();
                    }
                    break;
                case Formstate.ActivateNowError:
                    ///Validate the product key enter box to make sure it is not blank.  
                    if (FormValidator.Fieldisvalid(errorProvider1, middlePanel.Controls.Find("productKey", false)[0], "Please enter a valid Product Key.", validator))
                    {
                        SetFormActivateNowProcessing();
                    }
                    break;
                case Formstate.ActivateNowProcessingComplete:
                    DisplayRegistrationForm();
                    break;
                case Formstate.Buynowprocessingcomplete:
                    DisplayRegistrationForm();
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// The event handler for the back button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void back_Click(object sender, EventArgs e)
        {
            switch (m_eFormState)
            {
                case Formstate.SelectLicensing:
                    SetFormInitial();
                    break;
                case Formstate.Buynowprocessing:
                    SetFormSelectLicensingLevel();
                    m_buynowhelper.Cancelprocessing();
                    break;
                case Formstate.ActivateNow:
                    //SetFormSelectLicensingLevel();
                    SetFormInitial();
                    break;
                case Formstate.ActivateNowError:
                    SetFormInitial();
                    break;
                default:
                    Close();
                    break;
            }
        }

        /// <summary>
        /// Event handler for text changes in the product key entry box.  When the length of the product key
        /// is greater than 0 the next button is enabled, otherwise it's disabled.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void productKey_TextChanged(object sender, EventArgs e)
        {
            TextBox productKey;
            productKey = (TextBox) sender;
            if (productKey.Text.Length > 0)
            {
                next.Enabled = true;
            }
            else
            {
                next.Enabled = false;
            }
        }

        #endregion

        #region Private helper functions

        /// <summary>
        /// Initialize the state of the form
        /// </summary>
        private void SetFormInitial()
        {
            HideMiddlePanelControls();
            purchaseProductRadio.Visible = true;
            enterProductKeyRadio.Visible = true;
            back.Enabled = false;
            cancel.Enabled = true;
            next.Enabled = true;
            BackgroundImage = Resource.activation_options;
            m_eFormState = Formstate.Initial;
            Name = "Activation Options";
        }

        /// <summary>
        /// Set the form to display the available license levels for purchase and activation.
        /// </summary>
        private void SetFormSelectLicensingLevel()
        {
            int verticalIndex = 0;
            bool firstLicenseLevel = true;

            //Make the existing conrols invisible
            HideMiddlePanelControls();

            //set the form name and the background image
            Name = "Select a License Level";
            BackgroundImage = Resource.select_license;


            foreach (LicenseLevelsPrice availableLicenseLevel in dataStore.AvailableLicenseLevels)
            {
                if (!availableLicenseLevel.IsTrialLicensekey)
                {
                    var licenseSelection = new RadioButton();
                    var licenseSelectionDescription = new TextBox();

                    licenseSelection.Text = availableLicenseLevel.LicenseLevel + " (" + String.Format("{0:c}", availableLicenseLevel.LicenseLevelPrice) + ")";
                    licenseSelection.Name = "LicenseSelection";
                    licenseSelection.Tag = availableLicenseLevel;
                    licenseSelection.AutoSize = true;

                    licenseSelectionDescription.AutoSize = true;
                    licenseSelectionDescription.Name = "LicenseSelectionDescription";
                    licenseSelectionDescription.Text = availableLicenseLevel.Description;
                    licenseSelectionDescription.Multiline = true;
                    licenseSelectionDescription.ReadOnly = true;
                    licenseSelectionDescription.BorderStyle = BorderStyle.None;
                    licenseSelectionDescription.BackColor = Color.White;


                    if (firstLicenseLevel)
                    {
                        licenseSelection.Checked = true;
                    }

                    licenseSelection.Size = new Size(200, 22);
                    licenseSelection.Font = new Font("Microsoft Sans Serif", 11.25F, FontStyle.Bold, GraphicsUnit.Point, ((byte) (0)));
                    licenseSelection.Location = new Point(170, 105 + verticalIndex);
                    middlePanel.Controls.Add(licenseSelection);

                    licenseSelectionDescription.Size = new Size(350, 45);
                    licenseSelectionDescription.Font = new Font("Microsoft Sans Serif", 10.25F, FontStyle.Regular, GraphicsUnit.Point, ((byte) (0)));
                    licenseSelectionDescription.Location = new Point(170, 130 + verticalIndex);
                    middlePanel.Controls.Add(licenseSelectionDescription);

                    verticalIndex += 70;

                    firstLicenseLevel = false;
                }
            }

            back.Enabled = true;
            next.Enabled = true;

            m_eFormState = Formstate.SelectLicensing;
        }

        /// <summary>
        /// Set the  form for the Buy Now processing sequence.
        /// </summary>
        private void SetFormBuyNowProcessing()
        {
            RadioButton selectedLicenseLevel;
            LicenseLevelsPrice licenseLevel;

            foreach (Control control in middlePanel.Controls)
            {
                if (control.Name == "LicenseSelection")
                {
                    selectedLicenseLevel = (RadioButton) control;

                    if (selectedLicenseLevel.Checked)
                    {
                        licenseLevel = (LicenseLevelsPrice) selectedLicenseLevel.Tag;
                        m_buynowhelper.RequestedLicenseLevel = licenseLevel.LicenseLevel;
                        m_buynowhelper.RequestedLicenseLevelPrice = licenseLevel.LicenseLevelPrice.ToString();
                    }
                }
            }

            //launch the Paypal window
            var paymentThreadStarter = new ThreadStart(m_buynowhelper.Handlepayment);
            var paymentThread = new Thread(paymentThreadStarter);
            paymentThread.Start();


            //start the web service polling for a result of the Paypal transaction
            var handleProcessingThreadStarter = new ThreadStart(m_buynowhelper.Handleprocessing);
            var handleProcessingThread = new Thread(handleProcessingThreadStarter);
            handleProcessingThread.Start();

            //Make the existing conrols invisible
            HideMiddlePanelControls();

            //Set the header status text and center the label
            //this.headerLabel.Text = "Purchase a Product Key";
            Name = "Purchase a Product Key";
            //CenterLabel(headerLabel);
            BackgroundImage = Resource.purchase_key;

            ///Add the control to display the graphical network connection animation
            var webAnimation = new PictureBox();
            webAnimation.Anchor = AnchorStyles.None;
            webAnimation.Image = Resource.globeGIFanime;
            webAnimation.Location = new Point(170, 60);
            webAnimation.Name = "webAnimationIcon";
            webAnimation.Size = new Size(324, 72);
            webAnimation.TabIndex = 3;
            webAnimation.TabStop = false;
            middlePanel.Controls.Add(webAnimation);

            ///Add the label to display status text to the user
            var processingLabel = new Label();
            processingLabel.Anchor = AnchorStyles.None;
            processingLabel.Location = new Point(170, 150);
            processingLabel.Font = new Font("Microsoft Sans Serif", 8.75F, FontStyle.Regular, GraphicsUnit.Point, ((byte) (0)));
            processingLabel.Name = "processingLabel";
            processingLabel.AutoSize = true;
            processingLabel.Text = "Waiting for payment confirmation...";
            processingLabel.Size = new Size(150, 75);
            processingLabel.Visible = true;
            middlePanel.Controls.Add(processingLabel);
            CenterLabel(processingLabel);

            ///Set the state of the form buttons
            back.Enabled = true;
            cancel.Enabled = true;
            next.Enabled = false;

            ///Set the state of the form
            m_eFormState = Formstate.Buynowprocessing;
        }

        /// <summary>
        /// Set the form for the Activate now processing sequence.
        /// </summary>
        private void SetFormActivateNowProcessing()
        {
            string invoice = null;
            TextBox productKey;

            HideMiddlePanelControls();

            //Set the label text and center
            //this.headerLabel.Text = "Enter a Product Key";
            Name = "Enter a Product Key";
            //CenterLabel(headerLabel);
            BackgroundImage = Resource.enter_key;

            ///Add the control to display the graphical network connection animation
            var webAnimation = new PictureBox();
            webAnimation.Anchor = AnchorStyles.None;
            webAnimation.Image = Resource.globeGIFanime;
            webAnimation.Location = new Point(170, 60);
            webAnimation.Name = "webAnimationIcon";
            webAnimation.Size = new Size(324, 72);
            webAnimation.TabIndex = 3;
            webAnimation.TabStop = false;
            middlePanel.Controls.Add(webAnimation);

            ///Add the label to display status text to the user
            var processingLabel = new Label();
            processingLabel.Anchor = AnchorStyles.None;
            processingLabel.Location = new Point(170, 150);
            processingLabel.Font = new Font("Microsoft Sans Serif", 8.75F, FontStyle.Regular, GraphicsUnit.Point, ((byte) (0)));
            processingLabel.Name = "processingLabel";
            processingLabel.AutoSize = true;
            processingLabel.Text = "Waiting for product key confirmation...";
            processingLabel.Size = new Size(150, 75);
            processingLabel.Visible = true;
            middlePanel.Controls.Add(processingLabel);
            CenterLabel(processingLabel);

            ///Locate the product key text input in the middle panel and set the invoice private variable
            ///to be the text input
            foreach (Control c in middlePanel.Controls)
            {
                if (c.Name == "productKey")
                {
                    productKey = (TextBox) c;

                    invoice = productKey.Text;
                }
            }

            //buynowhelper.RequestedLicenseLevel = "Premium";

            ///Pass the invoice string to the buyNowHelper for processing with the web service.
            m_buynowhelper.Invoice = invoice;

            var paymentThreadStarter = new ThreadStart(m_buynowhelper.HandleProcessingInvoice);
            var paymentThread = new Thread(paymentThreadStarter);
            paymentThread.Start();


            ///Set the form buttons
            next.Enabled = false;
            back.Enabled = false;
            cancel.Enabled = true;

            ///Set the state of the form
            m_eFormState = Formstate.ActivateNowProcessing;
        }

        /// <summary>
        /// Set the form for a user to enter a product key.
        /// </summary>
        private void SetFormActivateNow()
        {
            HideMiddlePanelControls();

            //Set the label text and center
            //this.headerLabel.Text = "Enter a Product Key";
            Name = "Enter a Product Key";
            //CenterLabel(headerLabel);
            BackgroundImage = Resource.enter_key;

            ///Add the label to display status text to the user
            var activatingLabel = new Label();
            activatingLabel.Anchor = AnchorStyles.None;
            activatingLabel.Location = new Point(170, 105);
            activatingLabel.Font = new Font("Microsoft Sans Serif", 8.75F, FontStyle.Regular, GraphicsUnit.Point, ((byte) (0)));
            activatingLabel.Name = "processingLabel";
            activatingLabel.AutoSize = true;
            activatingLabel.Text = "Please enter your product key below:";
            activatingLabel.Size = new Size(150, 20);
            activatingLabel.Visible = true;
            middlePanel.Controls.Add(activatingLabel);

            ///If a product key entry box already exists remove it.
            if (middlePanel.Controls.IndexOfKey("productKey") >= 0)
            {
                middlePanel.Controls.RemoveByKey("productKey");
            }

            ///Add a product key entry box to the middle panel control.
            var productKey = new TextBox();
            productKey.Anchor = AnchorStyles.None;
            productKey.Location = new Point(170, 130);
            productKey.Name = "productKey";
            productKey.Size = new Size(240, 45);
            productKey.Visible = true;
            productKey.MaxLength = 50;
            middlePanel.Controls.Add(productKey);

            ///Add the event handler that monitors the user text input length and enables or disables
            ///the next button.
            productKey.TextChanged += new EventHandler(productKey_TextChanged);

            ///Set the button states.
            back.Enabled = true;
            cancel.Enabled = true;
            next.Enabled = false;

            ///Set the form state
            m_eFormState = Formstate.ActivateNow;
        }

        /// <summary>
        /// Displays the registration form and then closes the form
        /// </summary>
        private void DisplayRegistrationForm()
        {
            var register = new RegisterForm();
            Visible = false;
            register.ShowDialog(Owner);
            Close();
        }

        /// <summary>
        /// In case of a processing failure set the form state and display the failure message to the user.
        /// </summary>
        /// <param name="failureMessage">The failure message to display to the user.</param>
        private void SetFormBuyNowProcessingFailed(FailureInfo failureInfo)
        {
            HideMiddlePanelControls();

            ///If the user was trying to purchase a product key.
            if (m_eFormState == Formstate.Buynowprocessing)
            {
                var failureLabel = new TextBox();
                failureLabel.Anchor = AnchorStyles.None;
                failureLabel.Location = new Point(170, 105);
                failureLabel.Font = new Font("Microsoft Sans Serif", 8.75F, FontStyle.Regular, GraphicsUnit.Point, ((byte) (0)));
                failureLabel.Name = "failureLabel";
                failureLabel.ReadOnly = true;
                failureLabel.Multiline = true;
                failureLabel.BackColor = Color.White;
                failureLabel.BorderStyle = BorderStyle.None;
                failureLabel.AutoSize = true;
                failureLabel.TabStop = false;
                failureLabel.Text = "There was a problem with your product activation. " + failureInfo.Message;

                grfx = CreateGraphics();
                SizeF sizef = grfx.MeasureString(failureLabel.Text, failureLabel.Font, 300);
                failureLabel.Size = new Size(300, (int) sizef.Height + 50);


                failureLabel.Visible = true;
                middlePanel.Controls.Add(failureLabel);


                cancel.Text = "Close";
                back.Enabled = false;
                cancel.Focus();
                m_eFormState = Formstate.BuyNowError;

                if (failureInfo.Alert == FailureInfo.AlertType.Port)
                {
                    MessageBox.Show("If the web service cannot be reached please " + "verify that the ASP .NET development port matches the port " + "configured in the application web reference and update as " + "necessary.  The application will need to be restarted after " + "the configuration change.");
                }
            }

            ///If the user was trying to enter a product key.
            if (m_eFormState == Formstate.ActivateNowProcessing)
            {
                SetFormActivateNow();
                failureInfo.Message = "There was a problem with your product activation. " + failureInfo.Message;
                errorProvider1.SetError(middlePanel.Controls.Find("productKey", false)[0], failureInfo.Message);
                back.Enabled = true;
                m_eFormState = Formstate.ActivateNowError;
            }


            BackgroundImage = Resource.activation_unsuccessful;
            Name = "Activation Unsuccesful";


            //set the button states
            next.Enabled = false;
            cancel.Enabled = true;
        }

        ///<summary>
        /// When the processing is complete and successful set the form state to a successful completion
        /// and display the completion message.
        /// </summary>
        /// <param name="message">The completion message to display to the user.</param>
        private void SetFormBuyNowProcessingComplete(string message)
        {
            HideMiddlePanelControls();

            ///Set the header text for the form and center
            //this.headerLabel.Text = "Activation Complete";
            Name = "Activation Complete";
            //CenterLabel(headerLabel);
            BackgroundImage = Resource.activation_complete;

            ///Add the control to display the form completion text
            var completionLabel = new Label();
            completionLabel.Anchor = AnchorStyles.None;
            completionLabel.Location = new Point(170, 105);
            completionLabel.Font = new Font("Microsoft Sans Serif", 8.75F, FontStyle.Regular, GraphicsUnit.Point, ((byte) (0)));
            completionLabel.Name = "completionLabel";
            completionLabel.AutoSize = true;
            completionLabel.Text = message;
            completionLabel.Size = new Size(150, 100);
            completionLabel.Visible = true;
            middlePanel.Controls.Add(completionLabel);
            CenterLabel(completionLabel);

            var registerButton = new Button();
            registerButton.Location = new Point(170, 140);
            registerButton.Name = "next";
            registerButton.Size = new Size(120, 23);
            registerButton.TabIndex = 1;
            registerButton.Text = "Register";
            registerButton.Click += new EventHandler(next_Click);
            middlePanel.Controls.Add(registerButton);

            ///Set the button states
            //next.Enabled = true;
            //next.Text = "Register";
            cancel.Enabled = true;
            cancel.Text = "Close";
            back.Enabled = false;

            ///Set the form state
            m_eFormState = Formstate.Buynowprocessingcomplete;
        }


        /// <summary>
        /// This function will center a label based on it's parent control and the text width in the label.
        /// </summary>
        /// <param name="label">The label to be centered.</param>
        private void CenterLabel(Label label)
        {
            Graphics grfx = CreateGraphics();
            SizeF sizef = grfx.MeasureString(label.Text, label.Font);
            label.Location = new Point((label.Parent.Width - Convert.ToInt32(sizef.Width))/2, label.Location.Y);
        }

        /// <summary>
        /// This function hides all controls in the middle panel of the form.
        /// </summary>
        private void HideMiddlePanelControls()
        {
            foreach (Control c in middlePanel.Controls)
            {
                c.Visible = false;
            }
        }

        #endregion
    }
}